/*
 * Package il.ac.biu.cs.grossmm.impl.keys
 * File PatternFactory.java
 * Created on Sep 5, 2006
 *
 */
package il.ac.biu.cs.grossmm.api.keys;

import static il.ac.biu.cs.grossmm.api.keys.KeyPattern.*;

/**
 * Provides methods for creating key patterns using default implementation
 */
public class PatternFactory {
	/**
	 * Creates a new exact key pattern with a given value-type and pattern
	 * entries.
	 * 
	 * @param value
	 *            pattern value-type
	 * @param entries
	 *            pattern entries
	 * @return a new key pattern with a given value and pattern entries
	 */
	static public KeyPattern pattern(Object value, PatternEntry... entries)
	{
		return new ArrayKeyPattern(false, value, true, entries);
	}

	/**
	 * Creates a new exact key type-pattern with a given tyoe and pattern
	 * entries.
	 * 
	 * @param clazz
	 *            class representing the type
	 * @param entries
	 *            pattern entries
	 * @return a new key type-pattern with a given tyoe and pattern entries
	 */
	static public KeyPattern pattern(Class clazz, PatternEntry... entries)
	{
		return new ArrayKeyPattern(false, clazz, false, entries);
	}

	/**
	 * Creates a new exact key pattern with a null (=nil) pattern value and
	 * given pattern entries.
	 * 
	 * @param entries
	 *            pattern entries
	 * @return a new key pattern with a null (=nil) pattern value and given
	 *         pattern entries
	 */
	static public KeyPattern pattern(PatternEntry... entries)
	{
		return new ArrayKeyPattern(false, (Object) null, false, entries);
	}

	/**
	 * Creates a new mask key pattern with a given value-type and pattern
	 * entries.
	 * 
	 * @param value
	 *            pattern value-type
	 * @param entries
	 *            pattern entries
	 * @return a new key pattern with a given value and pattern entries
	 */
	static public KeyPattern maskPattern(Object value, PatternEntry... entries)
	{
		return new ArrayKeyPattern(true, value, true, entries);
	}

	/**
	 * Creates a new mask key type-pattern with a given tyoe and pattern
	 * entries.
	 * 
	 * @param clazz
	 *            class representing the type
	 * @param entries
	 *            pattern entries
	 * @return a new key type-pattern with a given type and pattern entries
	 */
	static public KeyPattern maskPattern(Class clazz, PatternEntry... entries)
	{
		return new ArrayKeyPattern(true, clazz, false, entries);
	}

	/**
	 * Creates a new exact key pattern with a null (=nil) pattern value and
	 * given pattern entries.
	 * 
	 * @param entries
	 *            pattern entries
	 * @return a new key pattern with a null (=nil) pattern value and given
	 *         pattern entries
	 */
	static public KeyPattern maskPattern(PatternEntry... entries)
	{
		return new ArrayKeyPattern(true, (Object) null, false, entries);
	}

	/**
	 * Creates a new mandatory pattern entry with a given attribute and
	 * (sub)pattern.
	 * 
	 * @param attribute
	 *            the pattern attribute
	 * @param pattern
	 *            the (sub)pattern
	 * @return a new mandatory pattern entry with the given attribute and
	 *         (sub)pattern
	 */
	static public PatternEntry mandatory(Attribute attribute, KeyPattern pattern)
	{
		return new PatternEntry(attribute, pattern, true);
	}

	/**
	 * Creates a new mandatory pattern entry with a given attribute and a value
	 * of a simple key (sub)pattern.
	 * 
	 * @param attribute
	 *            the attribute
	 * @param s
	 *            value of a simple key (sub)pattern
	 * @return a new mandatory pattern entry with a given attribute and a value
	 *         of a simple key (sub)pattern
	 */
	static public PatternEntry mandatory(Attribute attribute, Object s)
	{
		return new PatternEntry(attribute, pattern(s), true);
	}

	/**
	 * Creates a new mandatory pattern entry with a given attribute and a type
	 * of a simple key (sub)pattern.
	 * 
	 * @param attribute
	 *            the attribute
	 * @param c
	 *            type class of a simple key (sub)pattern
	 * @return a new mandatory pattern entry with a given attribute and a type
	 *         of a simple key (sub)pattern
	 */
	static public PatternEntry mandatory(Attribute attribute, Class c)
	{
		return new PatternEntry(attribute, pattern(c), true);
	}

	/**
	 * Creates a new mandatory pattern entry with a given attribuete and a
	 * ONLY_NULL_KEY (sub)pattern.
	 * 
	 * @param attribute
	 *            the attribute
	 * @return a new mandatory pattern entry with a given attribuete and a
	 *         ONLY_NULL_KEY (sub)pattern
	 */
	static public PatternEntry mandatory(Attribute attribute)
	{
		return new PatternEntry(attribute, ONLY_NULL_KEY, true);
	}

	/**
	 * Creates a new optional pattern entry with a given attribute and
	 * (sub)pattern.
	 * 
	 * @param attribute
	 *            the pattern attribute
	 * @param pattern
	 *            the (sub)pattern
	 * @return a new mandatory pattern entry with the given attribute and
	 *         (sub)pattern
	 */
	static public PatternEntry optional(Attribute attribute, KeyPattern pattern)
	{
		return new PatternEntry(attribute, pattern, false);
	}

	/**
	 * Creates a new optional pattern entry with a given attribute and a value
	 * of a simple key (sub)pattern.
	 * 
	 * @param attribute
	 *            the attribute
	 * @param s
	 *            value of a simple key (sub)pattern
	 * @return a new optional pattern entry with a given attribute and a value
	 *         of a simple key (sub)pattern
	 */
	static public PatternEntry optional(Attribute attribute)
	{
		return new PatternEntry(attribute, ONLY_NULL_KEY, false);
	}

	/**
	 * Creates a new optional pattern entry with a given attribute and a value
	 * of a simple key (sub)pattern.
	 * 
	 * @param attribute
	 *            the attribute
	 * @param s
	 *            value of a simple key (sub)pattern
	 * @return a new optional pattern entry with a given attribute and a value
	 *         of a simple key (sub)pattern
	 */
	static public PatternEntry optional(Attribute attribute, Object s)
	{
		return new PatternEntry(attribute, pattern(s), false);
	}

	/**
	 * Creates a new optional pattern entry with a given attribute and a type of
	 * a simple key (sub)pattern.
	 * 
	 * @param attribute
	 *            the attribute
	 * @param c
	 *            type class of a simple key (sub)pattern
	 * @return a new optional pattern entry with a given attribute and a type of
	 *         a simple key (sub)pattern
	 */
	static public PatternEntry optional(Attribute attribute, Class c)
	{
		return new PatternEntry(attribute, pattern(c), false);
	}

	// / simple operations

	/**
	 * Creates a new ley pattern with all entries in a given existing key
	 * pattern and the given entry (replaces the entry with the same attribute
	 * in the existing key pattern , if such entry exists). This operation does
	 * not change key patternprovided as an argument.
	 * 
	 * @param pattern
	 *            the base key
	 * @param entriey
	 *            key entry to add
	 */
	public static KeyPattern insert(KeyPattern pattern, PatternEntry entry)
	{
		return new ArrayKeyPattern(pattern, entry);
	}

}
